package com.cup.ali.sms.vcode;

import java.util.HashMap;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSON;

import com.cup.ali.sms.bean.SmsRequest;

/**
 * 验证码对外服务类
 */
public class Vcode implements Observer {

	private static Integer DEFAULT_SECOND = 60;
	
	private Map<String,Object> vcodeMap = new HashMap<>();
	
	private static Observer watcher = new Vcode();

	private static Logger logger = Logger.getLogger(Vcode.class);
	/**
	 * 受查者  : 60秒计时器
	 */
	private Observable timer = new VcodeTimer();
	
	public static Vcode build(){
		if(watcher==null) {
			watcher = new Vcode();
		}
		return (Vcode)watcher;
	}
	
	private Vcode(){}
	
	private Observable timer(){
		return timer;
	}
	
	@Override
	public void update(java.util.Observable obj, Object arg) {

		logger.info("验证码失效:" + JSON.toJSONString(arg));
		
		@SuppressWarnings("unchecked")
		Map<String,Object> params = (Map<String,Object>)arg;
		
		remove(String.valueOf(params.get("key")));
	}
	
	/**
	 * 移除验证码
	 * 
	 * @param key tel
	 */
	public void remove(String key){
		vcodeMap.remove(key);
		if(vcodeMap.size()==0){
			logger.info("no vcode clear...");
			VcodeTimer.threadPool .shutdown();
			VcodeTimer.threadPool = null;
			watcher=null;
		}
	}
	
	/**
	 * 记录验证码
	 * @param key tel
	 * @param vcode 验证码
	 */
	public void put(String key,Object vcode){
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("key", key);
		map.put("vcode", vcode);
		vcodeMap.put(key, vcode);
		reg(map);
	}

	public void put(SmsRequest sms) {
		Object code = sms.getTemplateParams().get("code");
		put(sms.getPhoneNumbers(),code);
	} 
	
	/**
	 * 根据tel获取对应的验证码
	 * @param key
	 * @return
	 */
	public String get(String key){
		Object vcode = vcodeMap.get(key);
		return vcode==null?null:String.valueOf(vcode);
	}
	/**
	 * 验证码校验
	 * @param key tel
	 * @param vCode 验证码
	 */
	public Boolean check(String key,String vCode){
		return vCode.equals(get(key).trim().toString());
	}
	
	/**
	 * 注册观察者
	 */
	private static void reg(Map<String, Object> map){
		Observer watcher = Vcode.build();
		/*默认计划时间为60s，如需调整修改参数@second*/
		((VcodeTimer)Vcode.build().timer()).add(watcher,map,Vcode.DEFAULT_SECOND);
	}
}
